﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Collections.ObjectModel;
using System.Windows.Forms;

using AtletIS.Shared.Entities;
using AtletIS.Shared.Helpers;
using AtletIS.Shared.Data;
using AtletIS.Shared.Data.aDbDataSetTableAdapters;

namespace AtletIS.Shared.Helpers
{
    public static class ChipResultHelper
    {

        #region CheckPoint

        /// <summary>
        ///  Tabuľka výsledkov pre check-point
        /// </summary>
        public static void CheckPointTable(DisciplineListEntity discipline, DataRow drCheckPoint, DataTable dtChipData, StreamWriter sw, bool bChipDateTime, bool bCleanChipDateTime, bool bDisplayBlock)
        {
            try
            {
                sw.WriteLine("<h3>Medzičas: " + drCheckPoint["Name"] + "</h3>");
                sw.WriteLine("<table class=\"main-table\">");

                #region Header row

                sw.WriteLine(" <tr height=\"30\" bgcolor=\"#ddd\">");
                sw.WriteLine("  <th width=\"40\" >Por.   </th>");
                sw.WriteLine("  <th width=\"50\" >Št.č.  </th>");
                sw.WriteLine("  <th width=\"50\"> Vlajka </th>");
                sw.WriteLine("  <th>Meno</th>");
                sw.WriteLine("  <th>Nar.</th> ");
                
                if (Globals.ActiveCompetition.ClubsCountries == true)
                    sw.WriteLine("  <th>Klub</th>");
                else
                    sw.WriteLine("  <th>Krajina</th>");

                if (bChipDateTime)
                {
                    sw.WriteLine("  <th width=\"65\">Čas</th>");
                    sw.WriteLine("  <th>Odstup</th>");
                }

                if (bCleanChipDateTime)
                {
                    sw.WriteLine("  <th width=\"65\">Čistý čas</th>");
                    sw.WriteLine("  <th>Odstup</th>");
                }
                
                sw.WriteLine(" </tr>");

                #endregion

                int rank = 1;
                DateTime leadingTime = new DateTime(), leadingTimeClean = new DateTime();

                foreach (DataRow drChipData in dtChipData.Rows)
                {
                    // Get time
                    TimeSpan? delayTime = null, delayTimeClean = null;
                    DateTime chipDateTime = (drChipData["ChipDateTime"] != DBNull.Value) ? Convert.ToDateTime(drChipData["ChipDateTime"]) : new DateTime();
                    DateTime chipDateTimeClean = ((drChipData["CleanChipDateTime"]) != DBNull.Value) ? Convert.ToDateTime(drChipData["CleanChipDateTime"]) : new DateTime();

                    // Round time
                    chipDateTime = RoundingHelper.RoundUpDateTime(chipDateTime, discipline.ResultCode);
                    chipDateTimeClean = RoundingHelper.RoundUpDateTime(chipDateTimeClean, discipline.ResultCode);

                    // Save leading time
                    if (rank == 1)
                    {
                        leadingTime = chipDateTime;
                        leadingTimeClean = chipDateTimeClean;
                    }
                    else
                    {
                        delayTime = chipDateTime - leadingTime;
                        delayTimeClean = chipDateTimeClean - leadingTimeClean;
                    }

                    // Rank, start number, flag, name, birth date, club/country
                    PrintHelper.PrintRowHeader(sw, rank);
                    sw.WriteLine("  <td align=\"center\">" + rank + "</td>");
                    sw.WriteLine("  <td align=\"center\">(" + drChipData["StartNumber"] + ")</td>");
                    sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintFlagImage(drChipData) +"</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintName(drChipData) + "</td>");
                    sw.WriteLine("  <td align=\"center\">" + Convert.ToDateTime(drChipData["BirthDate"]).Year + "</td>");
                    sw.WriteLine("  <td>" + PrintHelper.PrintClubCountry(Globals.ActiveCompetition.ClubsCountries, drChipData) + "</td>");

                    // Print time
                    if (bChipDateTime)
                    {
                        sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult2(chipDateTime, discipline.ResultCode) + "</td>");
                        
                        if (delayTime.HasValue)
                            sw.WriteLine("  <td align=\"center\">+" + PrintHelper.PrintResult2(delayTime.Value, discipline.ResultCode) + "</td>");
                        else
                            sw.WriteLine("  <td></td>");
                    }

                    // Print clean time
                    if (bCleanChipDateTime)
                    {
                        sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult2(chipDateTimeClean, discipline.ResultCode) + "</td>");

                        if (delayTimeClean.HasValue)
                            sw.WriteLine("  <td align=\"center\">+" + PrintHelper.PrintResult2(delayTimeClean.Value, discipline.ResultCode) + "</td>");
                        else
                            sw.WriteLine("  <td></td>");
                    }

                    sw.WriteLine(" </tr>");
                    rank += 1;
                }

                sw.WriteLine("</table>");
                sw.WriteLine("</div>");
                sw.WriteLine();
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        /// <summary>
        ///  Výsledky pre check-point
        /// </summary>
        public static void CheckPoint(DisciplineListEntity discipline, int checkPointOrder, bool bChipDateTime, bool bCleanChipDateTime)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(CH) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.UTF8);

            try
            {
                HtmlHelper.PrintHtmlHead(sw, "AtletIS");

                sw.WriteLine("<body>");

                HtmlHelper.PrintHeader(sw, discipline.Name + " - Medzičasy / Splits", Globals.ActiveCompetition);

                #region Get current check-point
                
                DataTable dtCheckpoint = DatabaseHelper.GetCheckPointsByDisciplineListIdAndOrder(discipline.ID, checkPointOrder); 
                if (dtCheckpoint.Rows.Count == 0)
                {
                    MessageBox.Show("Check-point #" + checkPointOrder.ToString() + " nie je definovaný.", "Chip results", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }
                DataRow drCheckpoint = dtCheckpoint.Rows[0];

                #endregion

                #region Print table

                int checkPointCode = Convert.ToInt32(drCheckpoint["Code"]);
                if (checkPointCode != 0)
                {
                    DataTable dtChipData = DatabaseHelper.GetChipDataByCheckPointId(Convert.ToInt32(drCheckpoint["ID"]));

                    if (dtChipData.Rows.Count > 0)
                    {
                        CheckPointTable(discipline, drCheckpoint, dtChipData, sw, bChipDateTime, bCleanChipDateTime, true);
                    }
                }

                #endregion

                HtmlHelper.PrintFooter(sw);

                sw.WriteLine("</body>");
                sw.WriteLine("</html>");

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        #region Discipline

        /// <summary>
        ///  Tabuľka výsledkov pre disciplínu
        /// </summary>
        public static void DisciplineTable(DisciplineListEntity discipline, bool bChipDateTime, bool bCleanChipDateTime, bool open, StreamWriter sw)
        {
            try
            {
                // Get check-points
                DataTable dtCheckpoints = DatabaseHelper.GetCheckPointsByDisciplineListId(discipline.ID); 
                if (dtCheckpoints.Rows.Count > 0)
                {
                    bool bFirstPrinted = false;

                    for (int i = dtCheckpoints.Rows.Count - 1; i >= 0; i--)
                    {
                        if (Convert.ToInt32(dtCheckpoints.Rows[i]["Code"]) == 1 | Convert.ToInt32(dtCheckpoints.Rows[i]["Code"]) == 2)
                        {
                            // Get chip data
                            DataTable dtChipData = DatabaseHelper.GetChipDataByCheckPointId(Convert.ToInt32(dtCheckpoints.Rows[i]["ID"]));
                            
                            if (dtChipData.Rows.Count > 0)
                            {
                                if (!bFirstPrinted)
                                {
                                    bFirstPrinted = true;
                                    CheckPointTable(discipline, dtCheckpoints.Rows[i], dtChipData, sw, bChipDateTime, bCleanChipDateTime, true);
                                }
                                else
                                {
                                    CheckPointTable(discipline, dtCheckpoints.Rows[i], dtChipData, sw, bChipDateTime, bCleanChipDateTime, false);
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        /// <summary>
        ///  Výsledky pre disciplínu
        /// </summary>
        public static void Discipline(DisciplineListEntity discipline, bool bChipDateTime, bool bCleanChipDateTime, bool open)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(CH) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.UTF8);

            try
            {
                Helpers.HtmlHelper.PrintHtmlHead(sw, "AtletIS");

                sw.WriteLine("<body>");

                HtmlHelper.PrintHeader(sw, discipline.Name + " - Medzičasy / Splits", Globals.ActiveCompetition);

                DisciplineTable(discipline, bChipDateTime, bCleanChipDateTime, open, sw);

                HtmlHelper.PrintFooter(sw);

                sw.WriteLine("</body>");
                sw.WriteLine("</html>");

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        #region StartNumber

        /// <summary>
        ///  Výsledky pre štartovné číslo
        /// </summary>
        public static void StartNumber(DisciplineListEntity discipline, int startNumber, bool bChipDateTime, bool bCleanChipDateTime)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(CH) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.UTF8);

            try
            {
                HtmlHelper.PrintHtmlHead(sw, "AtletIS");

                sw.WriteLine("<body>");

                HtmlHelper.PrintHeader(sw, "Medzičasy / Splits", Globals.ActiveCompetition);

                // Get chip data
                DataTable dtChipData = DatabaseHelper.GetChipDataByStartNumber(startNumber, Globals.ActiveCompetition.ID);

                if (dtChipData.Rows.Count > 0)
                {
                    // Print check-point header
                    sw.WriteLine("<h3>(" + dtChipData.Rows[0]["StartNumber"] + ") " + PrintHelper.PrintName(dtChipData.Rows[0]) + "</h3>");
                    sw.WriteLine("<table class=\"main-table\">");

                    #region Header

                    sw.WriteLine("<tr height=\"30\" bgcolor=\"#D8D8D8\">");
                    sw.WriteLine("  <th width=\"50\"  >Por.</th>");
                    sw.WriteLine("  <th>Prechod</th>");
                    
                    if (bChipDateTime)
                        sw.WriteLine("  <th>Čas</th>");
                    
                    if (bCleanChipDateTime)
                        sw.WriteLine("  <th>Čistý čas        </th>");

                    sw.WriteLine("</tr>");

                    #endregion

                    int rank = 1;
                    foreach (DataRow drChipData in dtChipData.Select(null, "ChipDateTime"))
                    {
                        // Get time
                        DateTime chipDateTime = (drChipData["ChipDateTime"] != DBNull.Value) ? Convert.ToDateTime(drChipData["ChipDateTime"]) : new DateTime();
                        DateTime chipDateTimeClean = ((drChipData["CleanChipDateTime"]) != DBNull.Value) ? Convert.ToDateTime(drChipData["CleanChipDateTime"]) : new DateTime();

                        // Round time
                        chipDateTime = RoundingHelper.RoundUpDateTime(chipDateTime, discipline.ResultCode);
                        chipDateTimeClean = RoundingHelper.RoundUpDateTime(chipDateTimeClean, discipline.ResultCode);

                        PrintHelper.PrintRowHeader(sw, rank);
                        sw.WriteLine("  <td align=\"center\">" + rank.ToString() + "</td>");
                        sw.WriteLine("  <td align=\"center\">" + drChipData["CheckPointName"].ToString() + "</td>");

                        if (bChipDateTime)
                            sw.WriteLine("  <td align=\"center\"><b> " + PrintHelper.PrintResult2(chipDateTime, discipline.ResultCode) + "</b></td>");

                        if (bCleanChipDateTime)
                            sw.WriteLine("  <td align=\"center\"><b> " + PrintHelper.PrintResult2(chipDateTimeClean, discipline.ResultCode) + "</b></td>");

                        sw.WriteLine("</tr>");
                        rank += 1;
                    }

                    sw.WriteLine("</table>");

                    HtmlHelper.PrintFooter(sw);

                    sw.WriteLine("</body>");
                    sw.WriteLine("</html>");

                    sw.Close();
                    sw.Dispose();

                    WordHelper.CreateWordFromHtml(htmlFilePath);
                }
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        #region Import

        /// <summary>
        ///  Import časov štartu do Performances
        /// </summary>
        public static void ImportStart(DisciplineListEntity discipline)
        {
            PerformancesTableAdapter taPermormances = new PerformancesTableAdapter();

            try
            {
                // Get performances
                aDbDataSet.PerformancesDataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);

                // Get finish check-point
                DataTable dtCheckpoints = DatabaseHelper.GetCheckPointsByDisciplineListIdStart(Globals.ActiveDiscipline.ID);
                if (dtCheckpoints.Rows.Count == 0)
                {
                    MessageBox.Show("Štartovný check-point nebol definovaný.", "Chipy - import času štartu", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return;
                }

                // Get ChipData
                int checkPointId = Convert.ToInt32(dtCheckpoints.Rows[0]["ID"]);
                DataTable dtChipData = DatabaseHelper.GetChipDataByCheckPointId(checkPointId);

                foreach (DataRow drChipData in dtChipData.Rows)
                {
                    dtPerformances.Select("StartNumber = " + drChipData["StartNumber"])[0]["RealStartTime"] = Convert.ToDateTime(drChipData["AbsoluteChipDateTime"]);
                }

                foreach (DataRow drPerformance in dtPerformances.Rows)
                {
                    if (Convert.ToInt32(drPerformance["RealStartTime"]) == 0)
                    {
                        drPerformance["Code"] = 4; // 4 = DNS
                    }
                }

                taPermormances.Update(dtPerformances);
                MessageBox.Show("Import prebehol úspešne.", "Chipy - import času štartu", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        /// <summary>
        ///  Import výsledkov do Performances
        /// </summary>
        public static void ImportFinish(DisciplineListEntity discipline, bool bClearChipDateTime)
        {
            PerformancesTableAdapter taPermormances = new PerformancesTableAdapter();

            try
            {
                string sortColumn = "ChipDateTime";

                if (bClearChipDateTime)
                    sortColumn = "CleanChipDateTime";
                
                // Get performances
                aDbDataSet.PerformancesDataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID); 

                // Get finish check-point
                DataTable dtCheckpoints = DatabaseHelper.GetCheckPointsByDisciplineListIdFinish(Globals.ActiveDiscipline.ID); 
                if (dtCheckpoints.Rows.Count == 0)
                {
                    MessageBox.Show("Cieľový check-point nebol definovaný.", "Import", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                int checkPointId = Convert.ToInt32(dtCheckpoints.Rows[0]["ID"]);
                DataTable dtChipData = DatabaseHelper.GetChipDataByCheckPointId(checkPointId);

                int rank = 1;
                DateTime chipDateTime;
                foreach (DataRow drChipData in dtChipData.Select(null, sortColumn))
                {
                    if (drChipData["ChipDateTime"] != DBNull.Value && drChipData["CleanChipDateTime"] != DBNull.Value)
                    {
                        if (bClearChipDateTime)
                            chipDateTime = Convert.ToDateTime(drChipData["CleanChipDateTime"]);
                        else
                            chipDateTime = Convert.ToDateTime(drChipData["ChipDateTime"]);

                        dtPerformances.Select("StartNumber = " + drChipData["StartNumber"])[0]["Result"] = TimeSpanHelper.ToDbResultString(chipDateTime.TimeOfDay);
                        dtPerformances.Select("StartNumber = " + drChipData["StartNumber"])[0]["Rank"] = rank;

                        rank += 1;
                    }
                }

                foreach (DataRow drPerformance in dtPerformances.Rows)
                {
                    if (Convert.ToInt32(drPerformance["Result"]) == 0)
                    {
                        drPerformance["Rank"] = 0;
                        drPerformance["Code"] = 3;
                    }
                }
                
                taPermormances.Update(dtPerformances);
                MessageBox.Show("Import prebehol úspešne.", "Chipy - import výkonov", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        #endregion

        #region Splits

        /// <summary>
        ///  Medzičasy z ChipData
        /// </summary>
        public static void Splits(DisciplineListEntity discipline, bool differences)
        {
            string htmlFilePath = HtmlHelper.GetNewHtmlFileName("(CH) " + discipline.Name);
            StreamWriter sw = new StreamWriter(htmlFilePath, false, Encoding.UTF8);

            try
            {
                HtmlHelper.PrintHtmlHead(sw, "Chip Splits");

                sw.WriteLine("<body>");

                HtmlHelper.PrintHeader(sw, "Medzičasy / Splits", Globals.ActiveCompetition);

                sw.WriteLine("<h3>" + discipline.Name + "</h3>");
                ChipResultHelper.SplitsTable(discipline, sw, differences);

                HtmlHelper.PrintFooter(sw);

                sw.WriteLine("</body>");
                sw.WriteLine("</html>");

                sw.Close();
                sw.Dispose();

                WordHelper.CreateWordFromHtml(htmlFilePath);
            }
            catch (Exception ex)
            {
                if (sw != null)
                {
                    sw.Close();
                    sw.Dispose();
                }

                ExceptionHelper.ShowErrorInfo(ex);
            }
        }

        /// <summary>
        ///  Tabuľka medzičasov z ChipData
        /// </summary>
        public static void SplitsTable(DisciplineListEntity discipline, StreamWriter sw, bool differences)
        {
            if (!discipline.RealStartTime.HasValue)
            {
                MessageBox.Show("Zadajte skutočný čas štartu.", "Tabuľka medzičasov");
                return;
            }
            
            // Get Performances
            DataTable dtPerformances = DatabaseHelper.GetPerformancesByDisciplineListId(discipline.ID);
            
            // Get CheckPoints
            DataTable dtCheckPoints = DatabaseHelper.GetCheckPointsByDisciplineListId(discipline.ID);

            // Get ChipData
            DataTable dtChipData = new DataTable();
            if (differences)
                dtChipData = DatabaseHelper.GetChipDataSplitsTableDiff(discipline.ID);
            else 
                dtChipData = DatabaseHelper.GetChipDataSplitsTable(discipline.ID);

            sw.WriteLine("<hr>");
            sw.WriteLine("<table class=\"extra\">");

            #region Header

            sw.WriteLine("<tr>");
            sw.WriteLine("  <td></td>");
            sw.WriteLine("  <td></td>");
            sw.WriteLine("  <td></td>");
            foreach (DataColumn col in dtChipData.Columns)
            {
                if (col.ColumnName != "ID" && !col.ColumnName.Contains("_Order"))
                {
                    if (dtCheckPoints.Select("ID = " + col.ColumnName).Count() > 0)
                    {
                        string checkPointName = dtCheckPoints.Select("ID = " + col.ColumnName)[0]["Name"].ToString();
                        sw.WriteLine("  <td align=\"center\"><b>" + checkPointName + "</b></td>");
                        sw.WriteLine("  <td align=\"center\"><b>#</b></td>");
                        sw.WriteLine("  <td align=\"center\" width=\"5px\"></td>");
                    }
                    
                }
            }
            sw.WriteLine("</tr>");

            #endregion

            #region Rows

            foreach (DataRow drPerformance in dtPerformances.Select("Rank > 0", "Rank"))
            {
                if (dtChipData.Select("ID = " + drPerformance["ID"].ToString()).Count() > 0)
                {
                    DataRow drChipData = dtChipData.Select("ID = " + drPerformance["ID"].ToString())[0];

                    sw.WriteLine("<tr>");
                    sw.WriteLine("  <td align=\"center\">" + drPerformance["Rank"].ToString() + "</td>");
                    sw.WriteLine("  <td align=\"center\">(" + drPerformance["StartNumber"].ToString() + ")</td>");
                    sw.WriteLine("  <td>" + drPerformance["Surname"].ToString().ToUpper() + " " + drPerformance["FirstName"].ToString() + "</td>");
                    foreach (DataColumn col in dtChipData.Columns)
                    {
                        if (col.ColumnName != "ID" && !col.ColumnName.Contains("_Order"))
                        {
                            DateTime dtChipDateTime = Convert.ToDateTime(drChipData[col.ColumnName]);
                            sw.WriteLine("  <td align=\"center\">" + PrintHelper.PrintResult2(dtChipDateTime, discipline.ResultCode) + "</td>");
                            sw.WriteLine("  <td align=\"center\">(" + drChipData[col.ColumnName + "_Order"] + ")</td>");
                            sw.WriteLine("  <td />");
                        }
                    }
                    sw.WriteLine("</tr>");
                }
            }

            #endregion

            sw.WriteLine("</table>");
        }

        #endregion

    }
}